package com.ctshk.rpc.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.system.dto.MainDataFieldDataDTO;
import com.ctshk.rpc.system.dto.MainDataRowDTO;
import com.ctshk.rpc.system.entity.MainDataField;
import com.ctshk.rpc.system.entity.MainDataFieldData;
import com.ctshk.rpc.system.entity.MainDataRowData;
import com.ctshk.rpc.system.mapper.MainDataFieldDataMapper;
import com.ctshk.rpc.system.mapper.MainDataFieldMapper;
import com.ctshk.rpc.system.mapper.MainDataRowDataMapper;
import com.ctshk.rpc.system.req.MainDataFieldDataReq;
import com.ctshk.rpc.system.req.MainDataRowDataReq;
import com.ctshk.rpc.system.service.IMainDataFieldDataService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

/**
 * <p>
 * 字段数据 服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2020-12-29
 */
@DubboService
public class MainDataFieldDataServiceImpl extends ServiceImpl<MainDataFieldDataMapper, MainDataFieldData> implements IMainDataFieldDataService {

    /**
     * 行数据
     */
    @Autowired
    private MainDataRowDataMapper mainDataRowDataMapper;

    /**
     * 表字段
     */
    @Autowired
    private MainDataFieldMapper mainDataFieldMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(MainDataRowDataReq mainDataRowDataReq, Long userId) {
        long tableId = mainDataRowDataReq.getTableId();
        MainDataRowData mainDataRowData = new MainDataRowData();
        mainDataRowData.setTableId(tableId);
        mainDataRowData.setSort(mainDataRowDataReq.getSort());
        mainDataRowData.setCreateId(userId);
        mainDataRowData.setIsDeleted(IsDeletedCode.NO.getCode());
        mainDataRowData.setStatus(mainDataRowDataReq.getStatus());
        LocalDateTime time = LocalDateTime.now();
        mainDataRowData.setGmtModified(time);
        mainDataRowData.setModifiedId(userId);
        int insert = mainDataRowDataMapper.insert(mainDataRowData);
        if (insert > 0) {
            Long rowId = mainDataRowData.getId();
            List<MainDataFieldDataReq> list = mainDataRowDataReq.getList();
            List<MainDataFieldData> dataFieldDataList = new ArrayList<>();
            MainDataFieldData mainDataFieldData = null;
            for (MainDataFieldDataReq mainDataFieldDataReq : list) {
                mainDataFieldData = new MainDataFieldData();
                BeanUtils.copyProperties(mainDataFieldDataReq, mainDataFieldData);
                mainDataFieldData.setCreateId(userId);
                mainDataFieldData.setTableId(tableId);
                mainDataFieldData.setRowId(rowId);
                mainDataFieldData.setModifiedId(userId);
                mainDataFieldData.setGmtModified(time);
                dataFieldDataList.add(mainDataFieldData);
            }
            List<MainDataFieldData> fieldDataList = dataField(userId, tableId, rowId, time, 1);
            if (CollectionUtils.isNotEmpty(fieldDataList)) {
                dataFieldDataList.addAll(fieldDataList);
            }
            super.saveBatch(dataFieldDataList);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateField(MainDataRowDataReq mainDataRowDataReq, Long userId) {
        //行数据实体类
        MainDataRowData mainDataRowData = new MainDataRowData();
        mainDataRowData.setTableId(mainDataRowDataReq.getTableId());
        mainDataRowData.setSort(mainDataRowDataReq.getSort());
        mainDataRowData.setStatus(mainDataRowDataReq.getStatus());
        LocalDateTime time = LocalDateTime.now();
        mainDataRowData.setGmtModified(time);
        mainDataRowData.setModifiedId(userId);
        //查询是否存在行数据
        MainDataRowData dataRowData = mainDataRowDataMapper.selectById(mainDataRowDataReq.getRowId());
        if (dataRowData == null) {
            //如果为空才写入行数据
            mainDataRowDataMapper.insert(mainDataRowData);
        } else {
            //更新行数据
            mainDataRowDataMapper.updateById(mainDataRowData);
        }
        //查询数据列表进行对比修改
        List<MainDataFieldData> oldMainDataFieldData = baseMapper.selectList(
                new QueryWrapper<MainDataFieldData>().lambda()
                        .eq(MainDataFieldData::getRowId, mainDataRowDataReq.getRowId())
                        .eq(MainDataFieldData::getIsDeleted, IsDeletedCode.NO.getCode())
        );
        //需要修改的数据集合
        List<MainDataFieldDataReq> mainDataFieldDataReqList = mainDataRowDataReq.getList();
        //转换实体类集合(实体类无对应id)
        List<MainDataFieldData> newMainDataFieldData = EntityUtil.copyList(mainDataFieldDataReqList, MainDataFieldData.class);
        HashMap<Long, MainDataFieldData> newMap = new HashMap<>(newMainDataFieldData.size());
        for (MainDataFieldData mainDataFieldData : newMainDataFieldData) {
            mainDataFieldData.setTableId(mainDataRowDataReq.getTableId());
            mainDataFieldData.setRowId(mainDataRowDataReq.getRowId());
            newMap.put(mainDataFieldData.getId(), mainDataFieldData);
        }

        HashMap<String, Long> idMap = new HashMap<>();
        List<MainDataFieldData> updateMainDataFieldData = new ArrayList<>();
        for (MainDataFieldData mainDataFieldData : oldMainDataFieldData) {
            Long fieldDataId = mainDataFieldData.getId();
            if (newMap.containsKey(fieldDataId)) {
                MainDataFieldData newData = newMap.get(fieldDataId);
                if (null != newData) {
                    updateMainDataFieldData.add(newData);
                    newMap.remove(fieldDataId);
                }
            } else {
                String key = mainDataFieldData.getTableId() + ":" + mainDataFieldData.getRowId() + ":" + mainDataFieldData.getFieldId();
                idMap.put(key, mainDataFieldData.getId());
            }
        }


        List<MainDataFieldData> addMainDataFieldData = new ArrayList<>(newMap.values());

        super.saveBatch(addMainDataFieldData);
        List<MainDataFieldData> fieldDataList = dataField(userId, mainDataRowDataReq.getTableId(), mainDataRowDataReq.getRowId(), LocalDateTime.now(), 2);
        if (CollectionUtils.isNotEmpty(fieldDataList)) {
            for (MainDataFieldData mainDataFieldData : fieldDataList) {
                String key = mainDataFieldData.getTableId() + ":" + mainDataFieldData.getRowId() + ":" + mainDataFieldData.getFieldId();
                mainDataFieldData.setId(idMap.get(key));
            }
            updateMainDataFieldData.addAll(fieldDataList);
        }
        super.updateBatchById(updateMainDataFieldData);
    }

    @Override
    @Transactional
    public void deleteRow(Long id, Long userId) {
        MainDataRowData mainDataRowData = mainDataRowDataMapper.selectById(id);
        if (mainDataRowData == null) {
            throw new BusinessException(SystemError.SYS_411);
        }
        //删除行
        mainDataRowDataMapper.deleteById(id);
        //删除行的列数据
        baseMapper.delete(new QueryWrapper<MainDataFieldData>().lambda().eq(MainDataFieldData::getRowId, id));
    }

    @Override
    public void updateStatus(Long id, Long userId) {
        MainDataRowData mainDataRowData = mainDataRowDataMapper.selectById(id);
        if (mainDataRowData == null) {
            throw new BusinessException(SystemError.SYS_411);
        }
        MainDataRowData dataRowData = new MainDataRowData();
        if (mainDataRowData.getStatus() == 1) {
            dataRowData.setStatus(0);
        } else {
            dataRowData.setStatus(1);
        }
        dataRowData.setGmtModified(LocalDateTime.now());
        dataRowData.setModifiedId(userId);
        mainDataRowDataMapper.updateById(dataRowData);
        MainDataFieldData mainDataFieldData = new MainDataFieldData();
        mainDataFieldData.setStatus(dataRowData.getStatus());
        mainDataFieldData.setGmtModified(LocalDateTime.now());
        mainDataFieldData.setModifiedId(userId);
        baseMapper.update(mainDataFieldData, new UpdateWrapper<MainDataFieldData>().lambda().eq(MainDataFieldData::getRowId, id));
    }

    @Override
    public MainDataRowDTO queryRow(Long id) {

        MainDataRowData mainDataRowData = mainDataRowDataMapper.selectById(id);
        List<MainDataFieldData> mainDataFieldDataList = baseMapper.selectList(
                new QueryWrapper<MainDataFieldData>().lambda()
                        .eq(MainDataFieldData::getIsDeleted, IsDeletedCode.NO.getCode())
                        .eq(MainDataFieldData::getStatus, 0)
                        .eq(MainDataFieldData::getRowId, id)
        );

        //将字段值放入内存map
        HashMap<Long, MainDataFieldData> hashMap = new HashMap<>(mainDataFieldDataList.size());

        for (MainDataFieldData mainDataFieldData : mainDataFieldDataList) {
            Long key = mainDataFieldData.getFieldId();
            hashMap.put(key, mainDataFieldData);
        }

        List<MainDataField> mainDataFieldList = mainDataFieldMapper.selectList(
                new QueryWrapper<MainDataField>().lambda()
                        .eq(MainDataField::getIsDeleted, IsDeletedCode.NO.getCode())
                        .eq(MainDataField::getStatus, 0)
                        .eq(MainDataField::getTableId, mainDataRowData.getTableId())
        );
        MainDataRowDTO mainDataRowDTO = new MainDataRowDTO();
        mainDataRowDTO.setId(id);
        List<MainDataRowDTO.FieldData> list = new ArrayList<>();
        MainDataRowDTO.FieldData fieldData = null;
        //构建返回体
        for (MainDataField mainDataField : mainDataFieldList) {
            fieldData = new MainDataRowDTO.FieldData();
            fieldData.setFieldName(mainDataField.getFieldName());
            MainDataFieldData mainDataFieldData = hashMap.get(mainDataField.getId());
            fieldData.setId(mainDataFieldData.getId());
            fieldData.setFieldValue(mainDataFieldData.getFieldValue());
            list.add(fieldData);
        }
        mainDataRowDTO.setList(list);

        return mainDataRowDTO;
    }

    @Override
    public MainDataFieldDataDTO queryFieldData(Long id) {
        MainDataFieldData mainDataFieldData = baseMapper.selectById(id);
        //先做返回null处理，等主数据有了再去掉  <= start => （叶冠峰）
        if (mainDataFieldData == null) {
            return null;
        }
        // <= end =>
        MainDataFieldDataDTO mainDataFieldDataDTO = new MainDataFieldDataDTO();
        BeanUtils.copyProperties(mainDataFieldData, mainDataFieldDataDTO);
        return mainDataFieldDataDTO;
    }

    public List<MainDataFieldData> dataField(Long userId, Long tableId, Long rowId, LocalDateTime time, Integer type) {
        List<MainDataField> mainDataFieldList = mainDataFieldMapper.selectList(
                new QueryWrapper<MainDataField>().lambda()
                        .eq(MainDataField::getTableId, tableId)
                        .eq(MainDataField::getIsFixed, 1)
                        .eq(MainDataField::getIsDeleted, IsDeletedCode.NO.getCode())
        );
        List<MainDataFieldData> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(mainDataFieldList)) {
            return list;
        }
        MainDataFieldData dataFieldData = null;
        for (MainDataField mainDataField : mainDataFieldList) {
            dataFieldData = new MainDataFieldData();
            dataFieldData.setCreateId(userId);
            dataFieldData.setTableId(tableId);
            dataFieldData.setRowId(rowId);
            dataFieldData.setFieldId(mainDataField.getId());
            dataFieldData.setGmtModified(time);
            dataFieldData.setModifiedId(userId);
            switch (mainDataField.getFieldName()) {
                case "修改人":
                    dataFieldData.setFieldValue(userId.toString());
                    break;
                case "修改时间":
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    String strDate = formatter.format(time);
                    dataFieldData.setFieldValue(strDate);
                    break;
                case "系统编码":
                    if (type == 2) {
                        dataFieldData.setFieldValue(makeRandomPassword(8));
                    }
                    break;
                default:
                    break;
            }

            list.add(dataFieldData);
        }
        return list;
    }


    public String makeRandomPassword(int len) {
        char[] random = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
        StringBuilder sb = new StringBuilder();
        Random r = new Random();
        for (int x = 0; x < len; ++x) {
            sb.append(random[r.nextInt(random.length)]);
        }
        return sb.toString();
    }
}
